home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Utilities / ODNewObj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  5.6 KB  |  247 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ODNewObj.cpp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <3>     1/23/96    VL        1170098: Put back the CFM loading code
  13.                                     removed in the last checkin. The code was
  14.                                     used for debugging and getting CFM errors.
  15.          <2>     1/16/96    VL        1170098: Removed code for GetSharedLibrary.
  16.  
  17.     To Do:
  18. */
  19.  
  20. /*
  21.     File:        ODNewObj.cpp
  22.  
  23.     Contains:    Abstract wrapper for instantiating objects by class-name
  24.  
  25.     Owned by:    Jens Alfke
  26.  
  27.     Copyright:    © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  28.         
  29. */
  30.  
  31. #ifndef _ODMEMORY_
  32. #include "ODMemory.h"
  33. #endif
  34.  
  35. #ifndef _ODNEWOBJ_
  36. #include "ODNewObj.h"
  37. #endif
  38.  
  39. #ifndef _PLFMDEF_
  40. #include "PlfmDef.h"
  41. #endif
  42.  
  43. #ifndef _EXCEPT_
  44. #include "Except.h"
  45. #endif
  46.  
  47. #ifndef _ODDEBUG_
  48. #include "ODDebug.h"
  49. #endif
  50.  
  51. #ifndef _ODUTILS_
  52. #include <ODUtils.h>
  53. #endif
  54.  
  55. #ifndef _PASCLSTR_
  56. #include <PasclStr.h>
  57. #endif
  58.  
  59. #ifndef _UTILERRS_
  60. #include "UtilErrs.h"
  61. #endif
  62.  
  63. #ifndef __SOM__
  64. #include <som.xh>
  65. #endif
  66.  
  67. #ifndef SOM_SOMClassMgr_xh
  68. #include <somcm.xh>
  69. #endif
  70.  
  71.  
  72. #ifdef _PLATFORM_MACINTOSH_
  73.  
  74.     #ifndef __STRINGS__
  75.     #include <strings.h>
  76.     #endif
  77.     
  78.     #include <CodeFragments.h>
  79.     
  80.     #define LOAD_UNDER_ASSUMED_NAME   1
  81.     /*    SOM requires that the library name (in the 'cfrg') be of the form "Module::ClassName".
  82.         This obviously won't match the library's SYM file name. This causes problems for source
  83.         level debuggers; they can't associate the two and you end up not being able to debug
  84.         the library.
  85.         To work around this, we give the library two names (two 'cfrg' entries), the second of
  86.         which is just the classname. Then if the SYM file name matches the classname, we can first
  87.         load the library by the classname, which will signal the debugger that it can link the
  88.         library up with the similarly-named SYM file.
  89.         Got that?? Off we go!!
  90.     */
  91. #endif
  92.  
  93. #ifndef _ODDEBUG_
  94. #include "ODDebug.h"
  95. #endif
  96.  
  97.  
  98. const ODSize kMinAppFreeSpace =        48 * 1024;
  99. const ODSize kMinAppContigSpace =     8 * 1024;
  100.  
  101. static somTD_SOMError            *gOld_SOMError;
  102.  
  103.  
  104. extern "C" {
  105.     static void
  106.     Temp_GetClass_SOMError( int error, corbastring filename, int linenum );
  107. }
  108.  
  109.  
  110. static void
  111. Temp_GetClass_SOMError( int error, corbastring filename, int linenum )
  112. {
  113.     int severity = error % 10;
  114.     if( severity == SOM_Fatal ) {
  115.         WARN("Fatal SOM err %d caught during GetClass; throwing...",error);
  116.         THROW(error);
  117.     } else if( gOld_SOMError )
  118.         gOld_SOMError(error,filename,linenum);
  119. }
  120.  
  121.  
  122. static SOMClass*
  123. GetClass( const char *className )
  124. {
  125.     ODRequireFreeSpace(kMinAppFreeSpace,kMinAppContigSpace,kODTrue);
  126.     
  127.     char libname[64];
  128.  
  129. #if LOAD_UNDER_ASSUMED_NAME
  130.     // First grab everything after the last colon in className:
  131.     const char *lastcolon = strrchr(className,':');
  132.     if (lastcolon == nil) {
  133.         // Hack to load Bento:
  134.         if( strcmp(className,"ODFileContainer")==0 ||
  135.             strcmp(className,"ODMemContainer")==0 ||
  136.             strcmp(className,"ODEmbeddedContainer")==0 )
  137.                 strcpy(libname, "OpenDoc Bento");
  138.         else
  139.                 strcpy(libname, className);
  140.     }
  141.     else {
  142.         strncpy(libname,lastcolon+1,sizeof(libname)-1);
  143.         libname[sizeof(libname)-1] = '\0';
  144.     }
  145. #else
  146.     strcpy(libname,className);
  147. #endif /*LOAD_UNDER_ASSUMED_NAME*/
  148.     
  149.     c2pstr(libname);
  150.  
  151.     CFragConnectionID connID;
  152.     Ptr mainAddr;
  153.     Str255 errName;
  154.     ODBoolean unloadLib = kODFalse;
  155.     
  156.     // First see if the library is already loaded:
  157.     OSErr err = GetSharedLibrary((StringPtr)libname, kCurrentCFragArch,
  158.                                 kFindCFrag, &connID,&mainAddr,errName);
  159.                                 
  160.     if( err == fragLibNotFound || err==fragLibConnErr ) {
  161.         // Nope, need to load it:
  162.         err = GetSharedLibrary((StringPtr)libname, kCurrentCFragArch,
  163.                                     kLoadCFrag, &connID,&mainAddr,errName);
  164.         if( err==noErr && !ODHaveFreeSpace(kMinAppFreeSpace,
  165.                                            kMinAppContigSpace,kODTrue) ) {
  166.             CloseConnection(&connID);
  167.             err = fragNoMem;
  168. #if ODDebug
  169.             CopyPascalString(errName,"\pOD free space too low");
  170. #endif
  171.         }
  172.         else
  173.             unloadLib = kODTrue;
  174.     }
  175.  
  176.     if( err ) {
  177.         p2cstr(errName);
  178.         WARN("Can't load lib '%s'; error %hd, '%s'",
  179.                 p2cstr((StringPtr)libname),err,errName);
  180.         THROW(err,(char*)errName);
  181.     }
  182.     
  183.     /* Now try to load the class. Install a temporary error handler that
  184.         converts a fatal SOM error into a THROW, in case SOM runs out of
  185.         memory. */
  186.     SOMClass *c;
  187.     gOld_SOMError = SOMError;
  188.     SOMError = &Temp_GetClass_SOMError;
  189.     TRY{
  190.         long majorVersion = 0;
  191.         long minorVersion = 0;
  192.         somId id = somIdFromString((corbastring)className);
  193.         c = somGetDynamicClassReference(id,majorVersion,minorVersion, kODNULL);
  194.         SOMFree(id);
  195.         if (unloadLib)
  196.         {
  197.             unloadLib = kODFalse;
  198.             CloseConnection(&connID);
  199.         }
  200.     }CATCH_ALL{
  201.         if (unloadLib)
  202.             CloseConnection(&connID);
  203.         SOMError = gOld_SOMError;
  204.         RERAISE;
  205.     }ENDTRY
  206.     SOMError = gOld_SOMError;
  207.         
  208.     
  209.     if( !c )
  210.         THROW(kODErrCantLoadSOMClass);
  211.     return c;
  212. }
  213.  
  214.  
  215. SOMObject*
  216. ODNewObject( const char *className )
  217. {
  218.     SOMClass *cls = GetClass(className);
  219.     THROW_IF_NULL (cls);  // would have thrown anyway...
  220.     SOMObject* obj = cls->somNew();
  221.     somReleaseClassReference(cls); // must release class reference
  222.     THROW_IF_NULL (obj); // similar to new ODObject, must throw if nil
  223.     return obj;
  224. }
  225.  
  226.  
  227. ODBoolean
  228. ODClassExists( const char *className )
  229. {
  230.     /* This function will now propagate errors if the library _does_ exist
  231.        but just couldn't be loaded due to e.g. insufficient memory or missing
  232.        imports. This allows for better error display to the user since otherwise
  233.        the error would be eaten and replaced with a simple Boolean return value. */
  234.     
  235.     ODBoolean result = kODTrue;
  236.     TRY
  237.         SOMClass *cls = GetClass(className);
  238.         somReleaseClassReference ( cls );
  239.     CATCH_ALL
  240.         if( ErrorCode()==kODErrCantLoadSOMClass || ErrorCode()==fragLibNotFound )
  241.             result = kODFalse;
  242.         else
  243.             RERAISE;
  244.     ENDTRY
  245.     return result;
  246. }
  247.